﻿using SkiaSharp;
using System;
using System.Globalization;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using yzrilyzr.util;

namespace FAQ_UI
{
	public class MyLabelTextBox : Panel
	{
		internal static readonly DependencyProperty HintProperty = DependencyProperty.Register("Hint", typeof(string), typeof(MyLabelTextBox), new UIPropertyMetadata(null, HintChange));
		private TimeAnim anim;
		private TextBox Box;

		public MyLabelTextBox()
		{
			anim = new MyTimeAnim(this, 300);
		}

		public string Hint
		{
			get => (string)GetValue(HintProperty);
			set => SetValue(HintProperty, value);
		}
		protected override Size ArrangeOverride(Size arrangeSize)
		{
			double labelH = getLabelH();
			Box.Arrange(new Rect(0, labelH, Box.DesiredSize.Width, Box.DesiredSize.Height));
			return arrangeSize;
		}
		private void setBox()
		{
			if (Box != null) return;
			Box = Children[0] as TextBox;
			Box.GotFocus += mGotFocus;
			Box.LostFocus += mLostFocus;
			Box.TextChanged += mTextChanged;
			mTextChanged(Box, null);
		}

		private void mTextChanged(object sender, TextChangedEventArgs e)
		{
			if ("" != Box.Text)
			{
				anim.setProgress(1);
				Invalidate();
			}
			else if (!Box.IsFocused) anim.reverse();
		}

		protected override Size MeasureOverride(Size constraint)
		{
			setBox();
			double labelH = getLabelH();
			Box.Measure(constraint);
			double mWidth = constraint.Width;
			if (Double.IsInfinity(mWidth)) mWidth = Box.DesiredSize.Width;
			Size size = new Size(Math.Max(Box.DesiredSize.Width, mWidth), Box.DesiredSize.Height + labelH);
			return size;
		}

		private void mLostFocus(object sender, RoutedEventArgs e)
		{
			mTextChanged(Box, null);
		}

		private void mGotFocus(object sender, RoutedEventArgs e)
		{
			anim.forward();
		}

		private static void HintChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			MyLabelTextBox dd = (MyLabelTextBox)d;
			dd.Invalidate();
		}

		private Typeface typeface = new Typeface("Arial");

		protected override void OnRender(DrawingContext drawingContext)
		{
			double lTextSIze = Box.FontSize * (1 - anim.value() * 0.2f);
			double labelH = getLabelH();
			byte alpha1 = (byte)(255 - 255 * anim.value());
			Color color1 = Color.FromArgb(alpha1, 128, 128, 128);
			var hintBrush = new SolidColorBrush(color1);
			var pt = new Point(0, labelH * (1 - anim.value()));
			var fmtt = new FormattedText(Hint, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, lTextSIze, hintBrush);
			drawingContext.DrawText(fmtt, pt);
			byte alpha2 = (byte)(255 * anim.value());
			Color color2 = Theme.Accent;
			color2.A = alpha2;
			var hintBrush2 = new SolidColorBrush(color2);
			fmtt = new FormattedText(Hint, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, lTextSIze, hintBrush2);
			drawingContext.DrawText(fmtt, pt);
		}

		private double getLabelH()
		{
			return Box.FontSize * 1.3;
		}

		private async void Invalidate()
		{
			await Task.Delay(10);
			InvalidateVisual();
		}

		private class MyTimeAnim : TimeAnim
		{
			private MyLabelTextBox e;

			public MyTimeAnim(MyLabelTextBox e, int time) : base(time)
			{
				this.e = e;
			}

			public override void onAnim()
			{
				e.Invalidate();
			}
			public override void requestNextRun()
			{
				mInvalidate();
			}
			private async void mInvalidate()
			{
				await Task.Delay(10);
				run();
			}
		}
	}
}